//
//  babyxfs_extract.c
//  BabyXFS project
//
//  Created by Malcolm McLean on 31/05/2024.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#include "bbx_filesystem.h"

/*
  load a text file into memory

*/
static char *fslurp(FILE *fp)
{
  char *answer;
  char *temp;
  int buffsize = 1024;
  int i = 0;
  int ch;

  answer = malloc(1024);
  if(!answer)
    return 0;
  while( (ch = fgetc(fp)) != EOF )
  {
    if(i == buffsize-2)
    {
      if(buffsize > INT_MAX - 100 - buffsize/10)
      {
    free(answer);
        return 0;
      }
      buffsize = buffsize + 100 * buffsize/10;
      temp = realloc(answer, buffsize);
      if(temp == 0)
      {
        free(answer);
        return 0;
      }
      answer = temp;
    }
    answer[i++] = (char) ch;
  }
  answer[i++] = 0;

  temp = realloc(answer, i);
  if(temp)
    return temp;
  else
    return answer;
}

void usage()
{
    fprintf(stderr, "babyxfs_extract Extrac ts a file for a FileSystem xml file\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Usage: babyfs_extract <directory.xml> <path>\n");
    fprintf(stderr, "\t<directory.xml> - FileSystem XML generated from the directory.\n");
    fprintf(stderr, "\t<path> - path to file in the directory to extract.\n");
    fprintf(stderr, "\t\tpath in the form \"/directory/subfolder/readme.txt\".\n");
    fprintf(stderr, "\tXML file generated by babyxfs_dirtoxml\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "By Malcolm McLean\n");
    fprintf(stderr, "Part of the BabyX project.\n");
    fprintf(stderr, "Check us out on github and get involved.\n");
    fprintf(stderr, "Program and source free to anyone for any use.\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    BBX_FileSystem *bbx_fs_xml = 0;
    BBX_FileSystem *bbx_fs_stdio = 0;
    FILE *fp;
    FILE *fp_stdio = 0;
    FILE *fp_xml = 0;
    int ch;
    char *xmlstring;
    int err;
    
    if (argc != 3)
        usage();

    fp = fopen(argv[1], "r");
    if (!fp)
    {
        fprintf(stderr, "Can't open xml file\n");
        exit(EXIT_FAILURE);
    }
    xmlstring = fslurp(fp);
    if (!xmlstring)
    {
        fprintf(stderr, "Out of memory\n");
        exit(EXIT_FAILURE);
    }
    fclose(fp);
    fp = 0;
    
    bbx_fs_xml = bbx_filesystem();
    err = bbx_filesystem_set(bbx_fs_xml, xmlstring, BBX_FS_STRING);
    if (err)
    {
        fprintf(stderr, "Can't set up XML filessystem\n");
        exit(EXIT_FAILURE);
    }
  
    fp_xml = bbx_filesystem_fopen(bbx_fs_xml, argv[2], "r");
    if (!fp_xml)
    {
            fprintf(stderr, "Can't open target file on xml system\n");
            exit(EXIT_FAILURE);
    }
    
    err = 0;
    while ((ch = fgetc(fp_xml)) != EOF)
        err |= (fputc(ch, stdout) == EOF) ? -1 : 0;
    
    if (err)
        fprintf(stderr, "errr writing file\n");
        
    err = bbx_filesystem_fclose(bbx_fs_xml, fp_xml);
    if (err)
        fprintf(stderr, "error closing xml file\n");
    
    bbx_filesystem_kill(bbx_fs_xml);
    free(xmlstring);
    
    exit(err ? EXIT_FAILURE : 0);
}

